package com.baichang.taoshunda.weixin.tencent;


import com.baichang.framework.utils.KidUtils;
import com.baichang.framework.utils.LogUtils;
import com.baichang.framework.utils.http.HttpUtils;
import com.baichang.taoshunda.weixin.tencent.model.ScanPayQueryReqData;
import com.baichang.taoshunda.weixin.tencent.model.UnifiedorderPayReqDate;
import com.baichang.taoshunda.weixin.tencent.model.WeChatRefundReqModel;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.weixin.pay.common.Constant;
import com.weixin.pay.common.RandomStringGenerator;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.*;

public class CompanyWeixinUtils {

    private static Map<String, String> getPayInfo(String name, int total_fee, String out_trade_no, String notify_url) {
        if (name != null && name.length() > 55) {
            name = name.substring(0, 55);
        }
        UnifiedorderPayReqDate unifiedorderPayReqDate = new UnifiedorderPayReqDate(
                CompanyConfigure.APP_ID, CompanyConfigure.MCH_ID, "", name, "", "",
                out_trade_no, "", total_fee, CompanyConfigure.getIP(), "", "", "",
                notify_url, "APP", "", "");
        String postDataXML = unifiedorderPayReqDate.toXml();
        postDataXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + postDataXML;
        try {
            String res = HttpUtils.postXml(CompanyConfigure.PAY_UNFIFIEDORDER,
                    postDataXML);
            if (CompanyConfigure.isDebug)
                LogUtils.getInstance().info(res);

            Map<String, String> map = XMLParser.xml2map(res);
            if (null != map) {
                String app_id = map.get("appid");
                String prepayid = map.get("prepay_id");
                Map<String, String> params = new HashMap<String, String>();
                params.put("appId", CompanyConfigure.APP_ID);
                params.put("partnerId", CompanyConfigure.MCH_ID);
                params.put("prepayId", prepayid);
                String noceStr = RandomStringGenerator
                        .getRandomStringByLength(32);
                String timeStamp = String
                        .valueOf((System.currentTimeMillis() / 1000));
                params.put("nonceStr", noceStr);
                params.put("timeStamp", timeStamp);
                params.put("package", "Sign=WXPay");

                List<NameValuePair> signParams = new LinkedList<NameValuePair>();
                signParams.add(new BasicNameValuePair("appid", app_id));
                signParams.add(new BasicNameValuePair("noncestr", noceStr));
                signParams.add(new BasicNameValuePair("package", "Sign=WXPay"));
                signParams.add(new BasicNameValuePair("partnerid",
                        CompanyConfigure.MCH_ID));
                signParams.add(new BasicNameValuePair("prepayid", prepayid));
                signParams.add(new BasicNameValuePair("timestamp", timeStamp));
                String sign = genAppSign(signParams);

                Map<String, String> outParams = new HashMap<String, String>();
                outParams.put("appid", CompanyConfigure.APP_ID);
                outParams.put("noncestr", noceStr);
                outParams.put("package", "Sign=WXPay");
                outParams.put("partnerid", CompanyConfigure.MCH_ID);
                outParams.put("prepayid", prepayid);
                outParams.put("out_trade_no", out_trade_no);
                outParams.put("timestamp", timeStamp);

                outParams.put("sign", sign);
                return outParams;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
//
//    public static Map<String, String> getCompanyPayInfo(String name,
//                                                        int total_fee, String out_trade_no) {
//        return getPayInfo(name,total_fee,out_trade_no,Configure.NOTIFY_URL);
//    }


    public static Map<String, String> getPayInfo(String name, int total_fee, String out_trade_no) {
//        System.out.print("aa");
        return getPayInfo(name, total_fee, out_trade_no, CompanyConfigure.NOTIFY_URL);
    }


    public static Map<String, String> payOrderquery(String out_trade_no) {
        ScanPayQueryReqData scanPayQueryReqData = new ScanPayQueryReqData(null,
                out_trade_no);
        // 解决XStream对出现双下划线的bug
        XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8",
                new XmlFriendlyNameCoder("-_", "_")));
        // 将要提交给API的数据对象转换成XML格式数据Post给API
        String postDataXML = xStreamForRequestPostData
                .toXML(scanPayQueryReqData);
        postDataXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + postDataXML;
        try {
            String res = HttpUtils.postXml(CompanyConfigure.PAY_QUERY_API,
                    postDataXML);
            if (CompanyConfigure.isDebug)
                LogUtils.getInstance().info(res);
            Map<String, String> map = XMLParser.xml2map(res);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    private static String genAppSign(List<NameValuePair> params) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < params.size(); i++) {
            sb.append(params.get(i).getName());
            sb.append('=');
            sb.append(params.get(i).getValue());
            sb.append('&');
        }
        sb.append("key=");
        sb.append(CompanyConfigure.KEY);
        String result = MD5.MD5Encode(sb.toString()).toUpperCase();
        return result;
    }


//    public static void main(String[] args) {
////      System.out.print(payMallRefund());
//
//        double aa = 1.10 * 100;
//        System.out.print((int)aa);
//    }


    /**
     * 商城 微信退款
     *
     * @return
     */
    public static boolean payMallRefund(String OutTradeNo, int TotalFee, int RefundFee) {
        WeChatRefundReqModel reqModel = new WeChatRefundReqModel();
        reqModel.setAppId(CompanyConfigure.APP_ID);
        reqModel.setMchId(CompanyConfigure.MCH_ID);
        reqModel.setNonoceStr(RandomStringGenerator.getRandomStringByLength(32));
        reqModel.setOpUserId(CompanyConfigure.MCH_ID);
//      reqModel.setTransactionId("4003442001201612011358472243");              //微信单号
        reqModel.setOutTradeNo(OutTradeNo);                                     //商户单号
        reqModel.setOutRefundNo(KidUtils.getKid());                             //退款单号
        reqModel.setTotalFee(TotalFee);                                         //总金额(分)
        reqModel.setRefundFee(RefundFee);                                       //退款金额(分）

        String refundSign = reqModel.toString() + "&key=" + CompanyConfigure.getKEY();
        String refundSignEncry = MD5.encryptMD5(refundSign).toUpperCase();
        String list = reqModel.toString() + "&sign=" + refundSignEncry;
        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
        for (String B : list.split("&")) {
            map.put(B.split("=")[0], B.split("=")[1]);
        }
        String refundXML = XMLParser.getXMLForMap(map);
        Map<String, String> resultMap = new HashMap<String, String>();
        try {

            String resultXML = doRefund(CompanyConfigure.REFUND_API, refundXML, CompanyConfigure.RefundCertificateAddress, CompanyConfigure.MCH_ID);
            resultMap = XMLParser.xml2map(resultXML);

        } catch (Exception e) {
            e.printStackTrace();
        }

        if (resultMap != null) {
            if (resultMap.get("result_code").toString().equals("SUCCESS")) {
                return true;
            }
        }
        return false;
    }


    public static String doRefund(String url, String data, String certPath, String mchId)
            throws Exception {
        /**
         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
         */

        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        FileInputStream instream = new FileInputStream(new File(certPath));//P12文件目录
        try {
            /**
             * 此处要改
             * */
            keyStore.load(instream, mchId.toCharArray());//这里写密码..默认是你的MCHID
        } finally {
            instream.close();
        }

        // Trust own CA and all self-signed certs
        /**
         * 此处要改
         * */
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray())//这里也是写密码的
                .build();
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,
                new String[]{"TLSv1"}, null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
            HttpPost httpost = new HttpPost(url); // 设置响应头信息
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
                return jsonStr;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }

    /**
     * 获取 微信 的openid
     *
     * @param jsCode
     * @return
     */
    public static Map<String, Object> jscode2session(String jsCode) {
        String url = Constant.JSCODE_SESSION_API + "?appid=" + CompanyConfigure.APP_ID + "&secret=" + CompanyConfigure.APP_SECRET + "&js_code=" + jsCode + "&grant_type=authorization_code";
        JSONObject map = null;
        String res = HttpUtils.get(url);

        try {
            map = JSONObject.fromObject(res);
            return map;
        } catch (Exception var6) {
            var6.printStackTrace();
            return null;
        }
    }


}
